package com.sunxd.zstudy.mybatise.domain.service.engine.dispatcher.interactive;

import com.google.common.collect.Maps;
import com.sunxd.zstudy.mybatise.domain.annotation.Handler;
import com.sunxd.zstudy.mybatise.domain.contans.enums.ConditionType;
import com.sunxd.zstudy.mybatise.domain.contans.enums.OperatorType;
import com.sunxd.zstudy.mybatise.domain.service.engine.handler.condition.ConditionHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Map;

/**
 * Description:
 */
@Component
@Slf4j
public class InteractiveConditionHandlerDispatcher implements ApplicationContextAware {

    private Map<ConditionType, Map<OperatorType, ConditionHandler>> conditionHandlerMap;

    public InteractiveConditionHandlerDispatcher() {
        this.conditionHandlerMap = Maps.newHashMap();
    }

    /**
     * 注册
     *
     * @param conditionType    条件类型
     * @param operatorType     操作类型
     * @param conditionHandler 条件处理器
     */
    public void register(ConditionType conditionType, OperatorType operatorType, ConditionHandler conditionHandler) {
        Map<OperatorType, ConditionHandler> map = conditionHandlerMap.get(conditionType);
        if (CollectionUtils.isEmpty(map)) {
            map = Maps.newHashMap();
        }
        map.put(operatorType, conditionHandler);
        conditionHandlerMap.put(conditionType, map);
    }

    /**
     * 获取
     *
     * @param conditionType 条件类型
     * @param operatorType  操作类型
     * @return
     */
    public ConditionHandler get(ConditionType conditionType, OperatorType operatorType) {
        Map<OperatorType, ConditionHandler> map = conditionHandlerMap.get(conditionType);
        if (!map.containsKey(operatorType)) {
            return map.get(OperatorType.DEFAULT);
        }
        return map.get(operatorType);
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        Map<String, Object> beanMap = applicationContext
                .getBeansWithAnnotation(Handler.class);
        for (Object bean : beanMap.values()) {
            if (bean instanceof ConditionHandler) {
                Handler annotation = bean.getClass().getAnnotation(Handler.class);
                ConditionType conditionType = annotation.conditionType();
                OperatorType operatorType = annotation.operatorType();
                register(conditionType, operatorType, (ConditionHandler) bean);
            }
        }
    }
}
